import backtrader as bt

class AverageStrategy (bt.Strategy):
    # 策略参数
    params = dict(
        period=20,  # 均线周期
        look_back_days=30,
        printlog=False,
        period_ema_fast=10,
        period_ema_slow=100,
        short_window=15,
        long_window=20,
        ssa_window=15
    )

    def __init__(self):
        for data in self.datas:
            # 五日移动平均线
            data.sma5 = bt.indicators.SimpleMovingAverage(data, period=5)
            # 十日移动平均线
            data.sma10 = bt.indicators.SimpleMovingAverage(data, period=10)
            data.sma20 = bt.indicators.SimpleMovingAverage(data, period=20)
            data.sma30 = bt.indicators.SimpleMovingAverage(data, period=30)
            data.sma60 = bt.indicators.SimpleMovingAverage(data, period=60)
            data.rsi = bt.indicators.RelativeStrengthIndex()



    def notify_order(self, order):
        """
        订单状态处理

        Arguments:
            order {object} -- 订单状态
        """
        if order.status in [order.Submitted, order.Accepted]:
            # 如订单已被处理，则不用做任何事情
            return

        # 检查订单是否完成
        if order.status in [order.Completed]:
            if order.isbuy():
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
                #print('BUY成交, 执行价={0}, {1}'.format(order.executed.price, order.executed.size))
            #elif order.issell():
                #print('SELL成交, 执行价={0}, {1}'.format(order.executed.price, order.executed.size))
            self.bar_executed = len(self)
        # 订单因为缺少资金之类的原因被拒绝执行
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        # 订单状态处理完成，设为空
        self.order = None

    def notify_trade(self, trade):
        """
        交易成果

        Arguments:
            trade {object} -- 交易状态
        """
        if not trade.isclosed:
            return

        # 显示交易的毛利率和净利润
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm), doprint=True)



    def next(self):
        #计算截面收益率
        rate_list=[]
        sorted_rate=sorted(rate_list,key=lambda x:x[1],reverse=True)
        long_list=[i[0] for i in sorted_rate[:10]]
        # 得到当前的账户价值
        total_value = self.broker.getvalue()
        for data in self.datas:
            #获取仓位
            pos = self.getposition(data).size
            if not pos :
                if  data.close[0]>data.open[0] and data.high[0]> data.sma5[0] and  data.high[0] > data.sma10[0]\
                        and data.high[0]> data.sma20[0]   and data.high[0]> data.sma30[0] \
                        and data.high[0]> data.sma60[0]   and data.low[0]< data.sma5[0] and  data.low[0] < data.sma10[0] \
                        and data.low[0]< data.sma20[0]    and  data.low[0] < data.sma30[0] and  data.low[0] > data.sma60[0]:
                    self.buy(data=data)
                    self.order = self.close(exectype=bt.Order.StopTrail, trailpercent=0.1)

            if pos!=0 :
                if  ( data.sma30[0]<data.sma60[0] or data.rsi > 80  ):
                    self.close(data = data)
    def log(self, txt, dt=None,doprint=False):
        if self.params.printlog or doprint:
            dt = dt or self.datas[0].datetime.date(0)
            print(f'{dt.isoformat()},{txt}')





